package com.fdd.spring.fddapplicationtext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilderFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

public class FddApplicationContext1 {
    private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();

    public FddApplicationContext1(String iocBeanXmlFile) throws Exception {
        // 1. 解析 XML 配置文件
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        Document document = factory.newDocumentBuilder()
                .parse(this.getClass().getResourceAsStream("/" + iocBeanXmlFile));

        // 2. 遍历 bean 定义
        NodeList beanNodes = document.getElementsByTagName("bean");
        for (int i = 0; i < beanNodes.getLength(); i++) {
            Element beanElement = (Element) beanNodes.item(i);
            String beanId = beanElement.getAttribute("id");
            String className = beanElement.getAttribute("class");

            // 3. 反射创建对象
            Class<?> clazz = Class.forName(className);
            Object instance = clazz.getDeclaredConstructor().newInstance();

            // 4. 属性赋值
            NodeList propertyNodes = beanElement.getElementsByTagName("property");
            for (int j = 0; j < propertyNodes.getLength(); j++) {
                Element prop = (Element) propertyNodes.item(j);
                String name = prop.getAttribute("name");
                String value = prop.getAttribute("value");

                // 构造 setter 方法名（如：setName）
                String methodName = "set" +
                        name.substring(0, 1).toUpperCase() + name.substring(1);

                // 获取字段类型进行类型转换
                Field field = clazz.getDeclaredField(name);
                Method method = clazz.getMethod(methodName, field.getType());

                // 执行 setter 方法
                if (field.getType() == Integer.class || field.getType() == int.class) {
                    method.invoke(instance, Integer.parseInt(value));
                } else {
                    method.invoke(instance, value);
                }
            }

            singletonObjects.put(beanId, instance);
        }
    }

    //创建getBean，传入id之后返回bean对象
    public Object getBean(String beanId) {
        return singletonObjects.get(beanId);
    }

}

